package com.heima.media.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.common.aliyun.GreenImageScan;
import com.heima.common.aliyun.GreenTextScan;
import com.heima.common.dto.ResponseResult;
import com.heima.common.minio.MinIOService;
import com.heima.common.util.SensitiveWordUtil;
import com.heima.media.dto.ArticleDto;
import com.heima.media.dto.ContentDto;
import com.heima.media.dto.ImageDto;
import com.heima.media.entity.*;
import com.heima.media.feign.ArticleFeign;
import com.heima.media.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.io.IOUtils;
import org.redisson.api.RDelayedQueue;
import org.redisson.api.RQueue;
import org.redisson.api.RedissonClient;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

import java.io.InputStream;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;

/**
 * 自动审核实现类
 *
 * @Name : AuditServiceImpl
 * @Author : WuQiang
 * @Date : 2022-10-11 23:24
 * @Description : 自动审核实现类
 */
@Service
@Slf4j
public class AuditServiceImpl implements IAuditService {

    @Autowired
    private GreenTextScan greenTextScan;
    @Autowired
    private GreenImageScan greenImageScan;
    @Autowired
    private IWmNewsService wmNewsService;
    @Autowired
    private MinIOService minIOService;
    @Autowired
    private ArticleFeign articleFeign;
    @Autowired
    private IWmUserService wmUserService;
    @Autowired
    private IWmChannelService wmChannelService;
    @Autowired
    private IWmSensitiveService wmSensitiveService;
    @Autowired
    private RedissonClient redissonClient;

    @Override
    @Async  //开启多线程方式执行此方法
    public void audit(WmNews wmNews) {
        String name = Thread.currentThread().getName();
        log.info("audit线程名称：{}", name);


        boolean isPass = true;
        //敏感词自审核
        isPass = checkSensitive(wmNews);
        if (!isPass) {
            return;
        }
        //文章和标题审核
        isPass = checkText(wmNews);
        if (!isPass) {
            return;
        }
        //图片审核
        isPass = checkImage(wmNews);
        if (!isPass) {
            return;
        }

        log.info("文本和图片都审核通过");

        //判断是否达到发布时间,远程article生成app文章
        if (System.currentTimeMillis() >= wmNews.getPublishTime().getTime()) {
            //发布
            Long articleId = saveArticle(wmNews);
            wmNews.setArticleId(articleId);
            wmNews.setStatus(9);
            wmNewsService.updateById(wmNews);
            log.info("发布成功");
        } else {
            //审核通过待发布 未到达发布时间
            wmNews.setStatus(8);
            wmNewsService.updateById(wmNews);

            //放延迟任务
            log.info("延迟发布");
            RQueue<Integer> rQueue = redissonClient.getBlockingQueue("article-queue");
            RDelayedQueue<Integer> delayedQueue = redissonClient.getDelayedQueue(rQueue);
            //需要延迟的时间  发布的时间减去当前时间  单位毫秒值
            long time = wmNews.getPublishTime().getTime() - System.currentTimeMillis();
            delayedQueue.offer(wmNews.getId(), time, TimeUnit.MILLISECONDS);
        }
    }

    @Override
    public Long saveArticle(WmNews wmNews) {
        ArticleDto articleDto = new ArticleDto();
        articleDto.setContent(wmNews.getContent());
        // articleDto.setId(); 雪花算法生成
        articleDto.setTitle(wmNews.getTitle());
        //根据id查询自媒体用户
        Integer userId = wmNews.getUserId();
        WmUser wmUser = wmUserService.getById(userId);
        articleDto.setAuthorId(wmUser.getApAuthorId());
        // articleDto.setAuthorName(wmUser.getName());
        //根据频道id查询频道信息
        WmChannel wmChannel = wmChannelService.getById(wmNews.getChannelId());
        articleDto.setChannelId(wmChannel.getId());
        articleDto.setChannelName(wmChannel.getName());
        articleDto.setLayout(wmNews.getType());
        articleDto.setFlag(0);
        //获取自媒体中的图片
        String images = wmNews.getImages();
        List<ImageDto> imageDtoList = JSON.parseArray(images, ImageDto.class);
        List<String> urlList = imageDtoList.stream().map(dto -> {
            return dto.getUrl();
        }).collect(Collectors.toList());
        articleDto.setImages(String.join(",", urlList));
        articleDto.setLabels(wmNews.getLabels());
        articleDto.setPublishTime(wmNews.getPublishTime());

        ResponseResult<Long> responseResult = articleFeign.saveArticle(articleDto);
        if (responseResult.getCode() == 0) {
            Long data = responseResult.getData();
            return data;
        } else {
            throw new RuntimeException("feign远程调用失败");
        }
    }

    private boolean checkSensitive(WmNews wmNews) {
        //获取文本
        String text = wmNews.getContent();
        List<ContentDto> contentDtoList = JSON.parseArray(text, ContentDto.class);
        for (ContentDto contentDto : contentDtoList) {
            if ("text".equals(contentDto.getType())) {
                text += contentDto.getValue();
            }
        }
        //构建DFA算法
        //获取所有的敏感词列表
        List<WmSensitive> sensitiveList = wmSensitiveService.list();
        List<String> list = sensitiveList.stream().map(wmSensitive -> {
            return wmSensitive.getSensitives();
        }).collect(Collectors.toList());
        SensitiveWordUtil.initMap(list);

        Map<String, Integer> map = SensitiveWordUtil.matchWords(text);
        if (map.size() > 0) {
            Set<String> keySet = map.keySet();
            wmNews.setStatus(2);
            wmNews.setReason("敏感词审核未通过，原因是包含以下敏感词:" + JSON.toJSONString(keySet));
            wmNewsService.updateById(wmNews);
            return false;
        } else {
            return true;
        }
    }

    private boolean checkImage(WmNews wmNews) {
        List<String> urlList = new ArrayList<>();
        //获取文章内容中的图片
        String content = wmNews.getContent();
        List<ContentDto> contentDtoList = JSON.parseArray(content, ContentDto.class);
        for (ContentDto contentDto : contentDtoList) {
            if ("image".equals(contentDto.getType())) {
                urlList.add(contentDto.getValue());
            }
        }
        //获取封面的图片
        //[{"id":43,"url":"https://myth.oss-cn-beijing.aliyuncs.com/2d9ffa21-ebef-46dc-89f9-15735c6e90e9.jpg"},
        // {"id":44,"url":"https://myth.oss-cn-beijing.aliyuncs.com/7b8d20ec-7ccf-4d4c-aac2-603b769e2e89.jpg"},
        String images = wmNews.getImages();
        List<ImageDto> imageDtoList = JSON.parseArray(images, ImageDto.class);
        for (ImageDto imageDto : imageDtoList) {
            if (!urlList.contains(imageDto.getUrl())) {
                urlList.add(imageDto.getUrl());
            }
        }
        try {
            List<byte[]> list = new ArrayList<>();
            //从MinIO中下载图片
            for (String url : urlList) {
                InputStream download = minIOService.download(url);
                byte[] bytes = IOUtils.toByteArray(download);
                list.add(bytes);
                //调用图片审核
                Map map = greenImageScan.imageScan(list);
                String suggestion = (String) map.get("suggestion");
                switch (suggestion) {
                    case "pass":
                        return true;
                    case "review":
                        wmNews.setStatus(3);
                        wmNews.setReason("图片需要人工审核，图片审核不通过的原因是:" + map.get("label"));
                        wmNewsService.updateById(wmNews);
                        return false;
                    case "block":
                        wmNews.setStatus(2);
                        wmNews.setReason("图片审核失败的原因是:" + map.get("label"));
                        wmNewsService.updateById(wmNews);
                        return false;
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }


        return false;
    }

    private boolean checkText(WmNews wmNews) {
        //获取文章标题
        String text = wmNews.getTitle();
        String content = wmNews.getContent();
        //        文章内容格式如下
/*       "[
       {
           "type":"text",
               "value":"随着智能手机的普及，人们更加习惯于通过手机来看新闻。由于生活节奏的加快，很多人只能利用碎片时间来获取信息，因此，对于移动资讯客户端的需求也越来越高。黑马头条项目正是在这样背景下开发出来。黑马头条项目采用当下火热的微服务+大数据技术架构实现。本项目主要着手于获取最新最热新闻资讯，通过大数据分析用户喜好精确推送咨询新闻"
       },
       {
           "type":"image",
               "value":"http://192.168.200.130/group1/M00/00/00/wKjIgl5swbGATaSAAAEPfZfx6Iw790.png",
               "id" :176
       }
]"*/
        List<ContentDto> contentDtos = JSON.parseArray(content, ContentDto.class);
        for (ContentDto contentDto : contentDtos) {
            if ("text".equals(contentDto.getType())) {
                text += contentDto.getValue();
            }
        }
        try {
            Map map = greenTextScan.greenTextScan(text);
            String suggestion = (String) map.get("suggestion");
            switch (suggestion) {
                case "pass":
                    return true;
                case "review":
                    wmNews.setStatus(3);
                    wmNews.setReason("文本需要人工审核，文本审核不通过的原因是:" + map.get("label"));
                    wmNewsService.updateById(wmNews);
                    return false;
                case "block":
                    wmNews.setStatus(2);
                    wmNews.setReason("文本审核失败的原因是:" + map.get("label"));
                    wmNewsService.updateById(wmNews);
                    return false;
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }
}
